package com.bridgeintelligent.tag.customer.provider;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.bridgeintelligent.tag.customer.entity.CustomersPage;
import com.bridgeintelligent.tag.customer.mapper.CustomersMapper;
import com.bridgeintelligent.tag.customer.mapper.ProviderMapper;
import com.bridgeintelligent.tag.customer.mapper.QueryModelMapper;
import com.bridgeintelligent.tag.customer.pojo.Filter;
import com.bridgeintelligent.tag.customer.pojo.FilterGroup;
import com.bridgeintelligent.tag.utils.FieldHandler;
import com.bridgeintelligent.tag.webserver.dim.query.api.CustQuerySetRsp;
import com.bridgeintelligent.tag.webserver.dim.query.api.service.IQueryService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
@Slf4j
public class ProviderServiceImpl implements IProviderService {

    private QueryModelMapper queryModelMapper;

    private ProviderMapper providerMapper;

    private static final String INIT_STR = "select cust_no,ecif_id,mobile_num,lvl_1_org_name,marke_authorization";

    private static final String TABLE_NAME0 = " from mktbd.cd_cust_alterable_label where 1 = 1 ";

    private static final String TABLE_NAME1 = " from jbps_shr.l99_fct_alterable_cust_tag where 1 = 1 ";

    private static Set<String> set = new HashSet<>();

    private IQueryService queryService;

    private CustomersMapper customersMapper;

    static {
        set.add("cust_no");
        set.add("ecif_id");
        set.add("mobile_num");
        set.add("lvl_1_org_name");
        set.add("marke_authorization");
    }

    @Override
    public String findFilterGroup(String customersId,String dataFrom) {
        //查询filter列表
        List<Filter> filters = new ArrayList<>();
        List<FilterGroup> filterGroups = findFilterGroup("-", customersId, filters);
        FilterGroup filterGroup = filterGroups.get(0);
        return sql(customersId,hander(filterGroup),dataFrom);
    }

    @Override
    public FilterGroup getFilterGroup(String customerId) {
        //查询filter列表
        List<Filter> filters = new ArrayList<>();
        List<FilterGroup> filterGroups = findFilterGroup("-", customerId, filters);
        return filterGroups.get(0);
    }

    @Override
    public List<CatalogInfoVO> findCatalogList() {
        List<CatalogInfoVO> result = providerMapper.getCatalogs();
        Map<String, List<CatalogInfoVO>> dimListMap = result.stream().collect(Collectors.groupingBy(CatalogInfoVO::getParentId));
        List<CatalogInfoVO> list = new ArrayList<>(result.size());
        Map<String, CatalogInfoVO> dimMap = result.stream()
                .collect(Collectors.toMap(CatalogInfoVO::getId, dimCatalog -> dimCatalog));
        List<CatalogInfoVO> parentList = dimListMap.get("-");
        parentList.forEach(dimCatalog -> list.add(findVO(dimListMap, dimMap, dimCatalog.getId())));
        parentList.sort(Comparator.comparing(CatalogInfoVO::getNumber));
        return parentList;
    }

    @Override
    public CustomersPage<DimInfoVO> getDimInfo(String catalogId,Integer pageNumber, Integer pageSize) {
        //获取父子目录关系
        List<CatalogModelVO> catalogModel = providerMapper.getCatalogModel();
        Map<String, CatalogModelVO> catalogMap = catalogModel.stream().collect(Collectors.toMap(CatalogModelVO::getId, v -> v));
        List<String> cataIds = null;
        if ( !StringUtils.isEmpty(catalogId)) {
            cataIds = new ArrayList<>();
            cataIds.add(catalogId);
            List<CatalogInfoVO> nexCataLogs = providerMapper.getNext(catalogId);
            if (!CollectionUtils.isEmpty(nexCataLogs)) {
                cataIds.addAll(nexCataLogs.stream()
                        .map(CatalogInfoVO::getId)
                        .collect(Collectors.toList()));
            }
        }
        Page page = PageHelper.startPage(pageNumber, pageSize);
        List<DimInfoVO> list = providerMapper.dimInfoList(cataIds);
        CustomersPage<DimInfoVO> dimInfoPage = new CustomersPage<>();
        dimInfoPage.setContent(list);
        dimInfoPage.setTotalPages(page.getPages());
        dimInfoPage.setTotalElements(page.getTotal());
        dimInfoPage.setSize(page.getPageSize());
        dimInfoPage.setRequestPager(pageNumber);
        return dimInfoPage;
    }

    @Override
    public CustQuerySetRsp custQuery(String customerId, Integer pageNumber, Integer pageSize) {

        pageNumber = pageNumber == null ? 0 : pageNumber;
        pageSize = pageSize == null ? 10 :pageSize;
        if (pageSize > 10000){
            CustQuerySetRsp resp = new CustQuerySetRsp();
            resp.setCode(-1);
            resp.setMsg("每页查询条数不能超过10000");
            return resp;
        }
        //获取客群主要信息
        CustQueryModel model = queryModelMapper.findInfoById(customerId);
        if (model == null){
            CustQuerySetRsp resp = new CustQuerySetRsp();
            resp.setCode(-1);
            resp.setMsg("客群不存在");
            return resp;
        }

        //如果是动态客群需要封装筛选条件
        if (FieldHandler.FALSE.equals(model.getDateType())){
            List<Filter> filters = new ArrayList<>();
            List<FilterGroup> filterGroups = findFilterGroup("-", customerId, filters);
            if (CollectionUtils.isEmpty(filterGroups)){
                CustQuerySetRsp resp = new CustQuerySetRsp();
                resp.setCode(-1);
                resp.setMsg("客群不存在!");
                return resp;
            }
            FilterGroup filterGroup = filterGroups.get(0);
            model.setFilterGroup(filterGroup);
        }
        //静态客群需要该值
        model.setCustomersId(customerId);
        //处理输出字段
        List<String> fieldList = JSON.parseArray(model.getFieldStr(), String.class);
        model.setFields(fieldList);
        //设置分页信息
        model.setFrom(pageNumber);
        model.setSize(pageSize);
        String condition = JSON.toJSONString(model);
        log.info("根据客群输出字段-查询条件："+condition);
        //ES查询
        return queryService.custQuery(condition);
    }

    @Override
    public boolean checkDataById(String customerId) {
        String dbId = customersMapper.checkDataById(customerId);
        if (StrUtil.isEmpty(dbId)){
            return false;
        }
        return true;
    }


    private CatalogInfoVO findVO(Map<String, List<CatalogInfoVO>> dimListMap, Map<String, CatalogInfoVO> dimMap, String id) {
        CatalogInfoVO dimCatalog = dimMap.get(id);
        List<CatalogInfoVO> list = dimListMap.get(dimCatalog.getId());
        if (null != list) {
            list.sort(Comparator.comparing(CatalogInfoVO::getNumber));
            list.forEach(dimCatalog1 -> {
                CatalogInfoVO catalogVOChirld = findVO(dimListMap, dimMap, dimCatalog1.getId());
                dimCatalog.getChildren()
                        .add(catalogVOChirld);
            });
        } else {
            return dimCatalog;
        }
        return dimCatalog;
    }

    private String sql(String customersId,String tiaojian,String dataFrom){
        StringBuffer buffer = new StringBuffer();
        String dimIds = providerMapper.findDims(customersId);
        if (StringUtils.isEmpty(dimIds)){
            buffer.append(INIT_STR);
            if (!StringUtils.isEmpty(dataFrom)){
                buffer.append(TABLE_NAME1);
            }else{
                buffer.append(TABLE_NAME0);
            }
            if (!StringUtils.isEmpty(tiaojian)){
                buffer.append(" and ").append(tiaojian);
            }
        }else{
            List<String> fileds = JSON.parseArray(dimIds, String.class);
            buffer.append(INIT_STR);
            for (int i = 0; i < fileds.size(); i++) {
                if (!set.contains(fileds.get(i))){
                    buffer.append(",").append(fileds.get(i));
                }
            }
            if (!StringUtils.isEmpty(dataFrom)){
                buffer.append(TABLE_NAME1);
            }else{
                buffer.append(TABLE_NAME0);
            }
            if (!StringUtils.isEmpty(tiaojian)){
                buffer.append(" and ").append(tiaojian);
            }
        }
        buffer.append(";");
        return buffer.toString();
    }


    @Override
    public CustomersPage<CustomerInfoVO> findPage(String userId, String customerName, String uptTimeStart, String uptTimeEnd, Integer pageNumber, Integer pageSize) {

        Map map = new HashMap();
        map.put("userId", userId);
        map.put("customerName", customerName);
        if (!StringUtils.isEmpty(uptTimeStart) && !StringUtils.isEmpty(uptTimeEnd)) {
            map.put("uptTimeStart", uptTimeStart);
            map.put("uptTimeEnd", uptTimeEnd + "23.59.59");
        }
        if (pageNumber == null){
            pageNumber = 1;
        }
        if (pageSize == null){
            pageSize = 10;
        }

        Page page = PageHelper.startPage(pageNumber, pageSize);
        List<CustomerInfoVO> list = providerMapper.findList(map);

        if (list != null && !list.isEmpty()) {
            List<FilterGroup> filterGroups ;
            for (CustomerInfoVO customer : list) {
                List<DimInfoVO> dimMsg = new ArrayList<>();
                //设置dimMsg
                if (!StringUtils.isEmpty(customer.getDimIds())){
                    String newStr = appendStr(customer.getDimIds());
                    List<String> fileds = JSON.parseArray(newStr, String.class);
                    customer.setDimIds(newStr);
                    if (!CollectionUtils.isEmpty(fileds)){
                        for (String field : fileds) {
                            //查出输出标签名
                            DimInfoVO infoVO = providerMapper.dimInfo(field);
                            dimMsg.add(infoVO);
                        }
                    }
                }
                customer.setDimMsg(dimMsg);
            }
        }
        CustomersPage<CustomerInfoVO> customersPage = new CustomersPage<>();
        customersPage.setContent(list);
        customersPage.setTotalPages(page.getPages());
        customersPage.setTotalElements(page.getTotal());
        customersPage.setSize(page.getPageSize());
        customersPage.setRequestPager(pageNumber);
        return customersPage;
    }

    private String appendStr(String dimIds){
        List<String> oldList = JSON.parseArray(dimIds, String.class);
        Set<String> oldSet = new HashSet<>(oldList);
        dimIds = dimIds.replace("]","");
        StringBuffer buffer = new StringBuffer();
        buffer.append(dimIds);
        for (String str:set) {
            if (!oldSet.contains(str)){
                buffer.append(",").append("\"").append(str).append("\"");
            }
        }
        buffer.append("]");
        return buffer.toString();
    }

    //查询条件组
    public  List<FilterGroup> findFilterGroup(String parentId, String customersId, List<Filter> filters) {
        Map<String, String> fgmap = new HashMap<>();
        fgmap.put("parentId", parentId);
        fgmap.put("customers_id", customersId);
        List<FilterGroup> filterGroupList = queryModelMapper.findFilterGroup(fgmap);
        Filter filter;
        List<Filter> filterList;
        if (filterGroupList != null && !filterGroupList.isEmpty()) {
            for (FilterGroup filterGroup : filterGroupList) {
                filterList = new ArrayList<>();
                //查找条件
                List<String> filterIds = queryModelMapper.findFilterIds(filterGroup.getId());
                if (filterIds != null && !filterIds.isEmpty()) {
                    for (String filterId : filterIds) {
                        filter = queryModelMapper.findOneFilterById(filterId);
                        filter.setValueList(JSON.parseArray(filter.getValueListStr(), String.class));
                        filterList.add(filter);
                        filters.add(filter);
                    }
                }
                filterGroup.setFilters(filterList);
                List<FilterGroup> list = findFilterGroup(filterGroup.getId(), customersId, filters);
                if (list != null && !list.isEmpty()) {
                    filterGroup.setChildren(list);
                }else{
                    filterGroup.setChildren(new ArrayList<FilterGroup>());
                }
            }
        }
        return filterGroupList;
    }

    public String hander(FilterGroup filterGroup){

        StringBuffer buffer = new StringBuffer();
        if (filterGroup != null) {
            if (!CollectionUtils.isEmpty(filterGroup.getFilters())) {
                for (int i = 0; i < filterGroup.getFilters().size(); i++) {
                    if (i == (filterGroup.getFilters().size() - 1)) {
                        buffer.append(" ( ");
                        buffer.append(getValue(filterGroup.getFilters().get(i)));
                        buffer.append(" ) ");
                    } else {
                        buffer.append(" ( ");
                        buffer.append(getValue(filterGroup.getFilters().get(i)));
                        buffer.append(" ) ");
                        buffer.append(filterGroup.getSymbol());
                    }
                }
            }
            if (!CollectionUtils.isEmpty(filterGroup.getChildren())) {
                if (!CollectionUtils.isEmpty(filterGroup.getFilters())){
                    buffer.append(filterGroup.getSymbol());
                }
                for (int i = 0; i < filterGroup.getChildren().size(); i++) {
                    if (i == filterGroup.getChildren().size()-1){
                        buffer.append(" ( ");
                        buffer.append(hander(filterGroup.getChildren().get(i)));
                        buffer.append(" ) ");
                    }else{
                        buffer.append(" ( ");
                        buffer.append(hander(filterGroup.getChildren().get(i)));
                        buffer.append(" ) ");
                        buffer.append(filterGroup.getSymbol());
                    }

                }
            }
        }
        return buffer.toString();
    }

    public String getValue(Filter filter){

        StringBuffer buffer = new StringBuffer();
        List<String> valueList  = JSON.parseArray(filter.getValueListStr(), String.class);
        String classify = filter.getClassify();//标签类型
        String type = filter.getType();
        String largeType = providerMapper.getLargeType(filter.getDimId());
        if ("03".equals(classify)){ //如果是数值类
            if (!"termNum".equals(type) && !"noTermNum".equals(type)){
                if ("02".equals(largeType)){
                    //如果是定制标签需要将标签ID转成字符串
                    buffer.append( " cast ( ").append(filter.getDimId()).append(" as string )");
                }else{
                    buffer.append( " cast ( ").append(filter.getDimId()).append(" as double )");
                }
            }else{
                buffer.append(filter.getDimId());
            }
        }else{
            if ("02".equals(largeType)){
                if (!"term".equals(type) && !"noTerm".equals(type)){
                    //如果是定制标签需要将标签ID转成字符串
                    buffer.append( " cast ( ").append(filter.getDimId()).append(" as string )");
                }else{
                    buffer.append(filter.getDimId());
                }
            }else{
                buffer.append(filter.getDimId());
            }
        }
        buffer.append(getCurrentMonth(filter.getDataDate()));

        if("01".equals(classify)){ //描述类型 keyword
            if ("contain_vague".equals(type)){ //包含
                buffer.append(" like '%").append(valueList.get(0)).append("%' ");
            }else if ("not_contain_vague".equals(type)){ //不包含
                buffer.append(" not like '%").append(valueList.get(0)).append("%' ");
            }else if ("term".equals(type)){ //存在
                buffer.append(" is not null ");
            }else if ("noTerm".equals(type)){ //不存在
                buffer.append(" is null ");
            }
        }else if ("02".equals(classify)){ //标志类 keyword
            if ("equal".equals(type)){ // 等于
                buffer.append(" = ").append("'").append(valueList.get(0)).append("' ");
            }else if ("no_equal".equals(type)){ // 不等于
                buffer.append(" != ").append("'").append(valueList.get(0)).append("' ");
            }else if ("contain".equals(type)){ //包含
                buffer.append(" in (").append(value(valueList)).append(") ");
            }else if ("not_contain".equals(type)){ //不包含
                buffer.append(" not in (").append(value(valueList)).append(") ");
            }else if ("term".equals(type)){ //存在
                buffer.append(" is not null ");
            }else if ("noTerm".equals(type)){ //不存在
                buffer.append(" is null ");
            }
        }else if ("03".equals(classify)){ //数值类 double
            if ("greater".equals(type)){ // 大于
                buffer.append(" > ").append(valueList.get(0)).append(" ");
            }else if ("less".equals(type)){ // 小于
                buffer.append(" < ").append(valueList.get(0)).append(" ");
            }else if ("greater_equal".equals(type)){ //大于等于
                buffer.append(" >= ").append(valueList.get(0)).append(" ");
            }else if ("less_equal".equals(type)){ // 小于等于
                buffer.append(" <= ").append(valueList.get(0)).append(" ");
            }else if ("equal".equals(type)){ // 等于
                buffer.append(" = ").append(valueList.get(0)).append(" ");
            }else if ("no_equal".equals(type)){ // 不等于
                buffer.append(" != ").append(valueList.get(0)).append(" ").append(" or ")
                        .append(filter.getDimId()).append(getCurrentMonth(filter.getDataDate())+" is null");
            }else if ("among".equals(type)){ //在。。。之中
                buffer.append(" between ").append(valueList.get(0)).append(" and ").append(valueList.get(1)).append(" ");
            }else if ("not_among".equals(type)){ //不在。。。之中
                buffer.append(" not between ").append(valueList.get(0)).append(" and ").append(valueList.get(1)).append(" or ")
                        .append(filter.getDimId()).append(getCurrentMonth(filter.getDataDate())+" is null");
            }else if ("termNum".equals(type)){ // 存在
                buffer.append(" is not null "); //不存在
            }else if ("noTermNum".equals(type)){
                buffer.append(" is null ");
            }
        }else if ("05".equals(classify)){ //日期类 date
            if ("greater".equals(type)){ // 大于
                buffer.append(" > '").append(valueList.get(0)).append("' ");
            }else if ("less".equals(type)){ //小于
                buffer.append(" < '").append(valueList.get(0)).append("' ");
            }else if ("greater_equal".equals(type)){ // 大于等于
                buffer.append(" >= '").append(valueList.get(0)).append("' ");
            }else if ("less_equal".equals(type)){ //小于等于
                buffer.append(" <= '").append(valueList.get(0)).append("' ");
            }else if ("equal".equals(type)){ //等于
                buffer.append(" = ").append("'").append(valueList.get(0)).append("' ");
            }else if ("no_equal".equals(type)){ //不等于
                buffer.append(" != ").append("'").append(valueList.get(0)).append("' ");
            }else if ("among".equals(type)){ // 在。。。之中
                buffer.append(" between '").append(valueList.get(0)).append("' and '").append(valueList.get(1)).append("' ");
            }else if ("not_among".equals(type)){ // 不在。。。之中
                buffer.append(" not between '").append(valueList.get(0)).append("' and '").append(valueList.get(1)).append("' ");
            }else if ("term".equals(type)){ // 存在
                buffer.append(" is not null "); //不存在
            }else if ("noTerm".equals(type)){
                buffer.append(" is null ");
            }
        }else if ("06".equals(classify)){ // 集合类 keyword
            if ("contain_everything".equals(type)){
                int i = 0;
                String name = buffer.toString();
                for (String value:valueList){
                    if(i==0){
                        i++;
                        buffer.append(" like '%").append(value).append("%' ");
                        continue;
                    }
                    buffer.append(" or ").append(name).append(" like '%").append(value).append("%' ");
                }
            }
        }
        return buffer.toString();
    }

    public static String value(List<String> valus){
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < valus.size(); i++) {
            if (i==valus.size()-1){
                buffer.append("'").append(valus.get(i)).append("'");
            }else{
                buffer.append("'").append(valus.get(i)).append("',");
            }
        }
        return buffer.toString();
    }

    /**
     * 处理特殊时间格式
     * @param dataDate
     * @return
     */
    public static String getCurrentMonth(String dataDate){
        String time = "";
        /*if (!"0".equals(dataDate)){
            time = "_"+dataDate+" ";
        }*/
        return time;
    }





}
